package beans;

import java.util.Date;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicSession;

import model.ACLMessage;
import model.Host;
import model.User;
import util.MessageDecryptor;
import beans.interfaces.AgentManagerLocal;
import beans.interfaces.ClientJMSListenerLocal;
@Singleton
@Startup
@LocalBean
public class ClientJMSListener implements MessageListener, ClientJMSListenerLocal {
	
	private TopicConnection connection;
	private TopicSession session;
	private MessageConsumer consumer;
	private MessageProducer producer;
	private model.Message clientsMessage;
	private model.User dummyUser = new User("agent centre", "centre", new Host());
	
	@Resource(mappedName = "java:/ConnectionFactory")
	private ConnectionFactory connectionFactory;
    
    @Resource(mappedName = "java:/topic/mojTopic")
    private Topic topic;
    
    @Resource(mappedName = "java:/topic/mojTopic2")
    private Topic topic2;
    
    @EJB
    private AgentManagerLocal agentManager;
    
    public ClientJMSListener() {

    }
    @Override
    public void onMessage(Message message) {
		model.Message userMessage=null;
		try {
			userMessage = MessageDecryptor.decryptUserMessage(message);
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassCastException cce) {
			return;
		}
		if(userMessage!=null) {
			String content=null;
			if(!userMessage.getFrom().equals(dummyUser)) {
				clientsMessage = (model.Message) userMessage;
				if(clientsMessage!=null) {
					content=clientsMessage.getContent();					
					if(content!=null) {
						//agentManager.recieveRequest(content);
						try {
							//open connections, send message, close connections
							TopicConnection connection2 = (TopicConnection)connectionFactory.createConnection("guest", "guestguest");
							TopicSession session2 = connection2.createTopicSession(false,
							        Session.AUTO_ACKNOWLEDGE);
							connection2.start();
							MessageProducer producer2 = session2.createProducer(topic2);
							//ACLMessage aclMessage = new ACLMessage(agentManager.getManagerAgentInfo(), agentManager.findAgentInfo("master0"),"call for proposal", content);
							//find any master agent for the tender
							ACLMessage aclMessage = new ACLMessage(agentManager.getManagerAgentInfo(), agentManager.findAnyTenderStarter(),"call for proposal", content);
							ObjectMessage objMsg= session.createObjectMessage();
							objMsg.setObject(aclMessage);
							//send object message
							producer2.send(objMsg);
							connection2.close();
							session2.close();
							producer2.close();
						} catch (JMSException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
				}
			}
		}
    }
    
	@PostConstruct
	public void connect() {
		try {
			connection = (TopicConnection)connectionFactory.createConnection("guest", "guestguest");
			session = connection.createTopicSession(false,
			        Session.AUTO_ACKNOWLEDGE);
			connection.start();
			consumer = session.createConsumer(topic);
			consumer.setMessageListener(this);
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@PreDestroy
	public void disconnect() {
		try {
			consumer.close();
			connection.stop();
			connection.close();
			session.close();
			//producer.close();
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void sendTenderResultToClient(ACLMessage msg) {
		// TODO Auto-generated method stub
		if(msg instanceof ACLMessage) {
			String protocol = msg.getProtocol();
			if(protocol!=null) {
				if(protocol.contains("tender done")) {
					try {
						producer = session.createProducer(topic);
						model.Message replyMessage = new model.Message(dummyUser,clientsMessage.getFrom(),new Date(),msg.getContent());
						ObjectMessage objMsg = session.createObjectMessage();
						objMsg.setObject(replyMessage);
						producer.send(objMsg);
						producer.close();
					} catch (JMSException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}

}
